package main;

import java.io.IOException;

import org.apache.log4j.Logger;
import org.jibble.pircbot.PircBot;

/**
 * This class is used to share the burdens with the main bot. It connects as its own entity, and can help with outputting command
 * responses and such. It only reads from PM's, and leaves reading from channels to the main bot instance
 * 
 * 
 */
public class Worker extends PircBot {
   public final String nick;
   private final String password;
   private boolean finishedConnecting = false;

   public Worker(final String nick, final String password) {
	  this.nick = nick;
	  this.password = password;
   }

   /**
    * Makes this worker connect to IRC
    */
   public void connectToIRC() {
	  setVerbose(false);
	  setName(nick);
	  setAutoNickChange(true);
	  for (int i = 0; i < 200; ++i) {
		 boolean connected = true;
		 try {
			connect(Main.getBotSettings().getIrcServer());
		 } catch (final IOException e) {
			Logger.getLogger("Error").error("", e);
			connected = false;
		 } catch (final Exception e) {
			Logger.getLogger("Error").error("", e);
		 }
		 if (connected) {
			break;
		 } else {
			try {
			   Thread.sleep(30000);
			} catch (final InterruptedException e) {
			}
		 }
	  }

	  if (isConnected()) {
		 identify(password);
	  }
   }

   @Override
   public void disconnect() {
	  synchronized (this) {
		 this.quitServer();
	  }
   }

   /**
    * Not used, so just calling the base equals
    */
   @Override
   public boolean equals(final Object o) {
	  return super.equals(o);
   }

   /**
    * Returns the state of connection for this worker
    * 
    * @return
    */
   public boolean finishedConnecting() {
	  return finishedConnecting;
   }

   @Override
   public int hashCode() {
	  assert false : "hashCode not designed";
	  return 42; // any arbitrary constant will do
   }

   @Override
   protected void onDisconnect() {
	  Bot.getInstance().workerDisconnect();
	  finishedConnecting = false;
   }

   @Override
   protected void onInvite(final String targetNick, final String sourceNick, final String sourceLogin,
		 final String sourceHostname, final String channel) {
	  if (targetNick.equals(nick)
			&& (channel.equalsIgnoreCase(Main.getBotSettings().getMainChannel()) || channel.equalsIgnoreCase(Main.getBotSettings().getAdminChannel()))) {
		 this.joinChannel(channel);
	  }
   }

   @Override
   protected void onNotice(final String sourceNick, final String sourceLogin, final String sourceHostname, final String target,
		 final String notice) {
	  if ("NickServ".equals(sourceNick) && target.equals(nick)) {
		 if ("Your nickname isn't registered.".equals(notice)) {
			Bot.getInstance().sendMessage("NickServ", "GHOST " + nick + " " + password);
			try {
			   Thread.sleep(3000);
			} catch (final InterruptedException e) {
			   Logger.getLogger("Error").error("", e);
			}
			changeNick(nick);
			identify(password);
		 } else if ("Password accepted -- you are now recognized.".equals(notice)) {
			joinChannel(Main.getBotSettings().getMainChannel()
				  + ("".equals(Main.getBotSettings().getMainChannelPw()) ? "" : " " + Main.getBotSettings().getMainChannelPw()));
			if (!"".equals(Main.getBotSettings().getAdminChannel())) {
			   joinChannel(Main.getBotSettings().getAdminChannel()
					 + ("".equals(Main.getBotSettings().getAdminChannelPw()) ? "" : " "
						   + Main.getBotSettings().getAdminChannelPw()));
			}
			synchronized (this) {
			   finishedConnecting = true;
			   notify();
			}
		 }
	  }
   }

   @Override
   protected void onPrivateMessage(final String sender, final String handler, final String message) {
	  Bot.getInstance().onPrivateMessage(sender, nick, message);
   }

   @Override
   protected void onServerResponse(final int code, final String response, final String channel) {
	  if (code == 473 || code == 474 || code == 475) {
		 if (response.split(" ")[1].equals(Main.getBotSettings().getMainChannel())) {
			sendRawLine("cs invite " + Main.getBotSettings().getMainChannel());
		 } else if (response.split(" ")[1].equals(Main.getBotSettings().getAdminChannel())) {
			sendRawLine("cs invite " + Main.getBotSettings().getAdminChannel());
		 }
	  }
   }
}
